package com.xinhe.web.service;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.xinhe.web.common.BusinessException;
import com.xinhe.web.common.Result;
import com.xinhe.web.entity.*;
import com.xinhe.web.reposity.*;
import com.xinhe.web.response.AttachView;
import com.xinhe.web.response.SellerShopDetailView;
import com.xinhe.web.session.UserSessionManager;
import com.xinhe.web.vo.UserRoleModel;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.inject.Provider;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SellerShopService {
    @Autowired
    private SellerShopRepository sellerShopRepository;
    @Autowired
    private MemberRepository memberRepository;
    @Autowired
    private LocalUserRepository localUserRepository;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    GoodsRepository goodsRepository;
    @Autowired
    AttachService attachService;
    @Autowired
    private UserSessionManager userSessionManager;
    @Autowired
    OrderRepository orderRepository;
    @Autowired
    WithdrawalsRecordRepository withdrawalsRecordRepository;
    @Autowired
    private AssetDetailRepository assetDetailRepository;

    //查询工厂
    private JPAQueryFactory queryFactory;
    @Autowired
    private Provider<EntityManager> entityManager;
    @PostConstruct
    public void init() {
        queryFactory = new JPAQueryFactory(entityManager);
    }
    public QueryResults<SellerShop> pageSellerShop(String name, int pageNum, int pageSize) {
        QSellerShop qSellerShop = QSellerShop.sellerShop;
        BooleanBuilder builder = new BooleanBuilder();
        if (StringUtils.isNotEmpty(name)) {
            builder.and(qSellerShop.name.contains(name));
        }
        return queryFactory.select(
                Projections.bean(
                        SellerShop.class,
                        qSellerShop.name,
                        qSellerShop.fUserId,
                        qSellerShop.userName,
                        qSellerShop.id,
                        qSellerShop.iconPath,
                        qSellerShop.projects,
                        qSellerShop.userName,
                        qSellerShop.mobile,
                        qSellerShop.status
                )
        ).from(qSellerShop).where(builder).offset(pageNum * pageSize).limit(pageSize).fetchResults();
    }
    @Transactional
    public Result saveSellerShop(Long userId, String iconPath, String name, String projects, String userName, String mobile) {
        SellerShop sellerShop = this.sellerShopRepository.findByUserIdAndNotStatus(userId,"FAILURE");
        if (sellerShop != null) {
            if (sellerShop.getStatus().equals("SUCCESS")) {
                throw new BusinessException(5001,"您提交的商家入驻申请认证已通过,请不要重复提交");
            }
            if (sellerShop.getStatus().equals("NONE")) {
                throw new BusinessException(5002,"您已提交过商家入驻认证申请,请不要重复提交");
            }
        }
        SellerShop sellerShopByName = this.sellerShopRepository.findByName(name);
        if (sellerShopByName != null) {
            throw new BusinessException(5003,"店铺名称已存在");
        }
        sellerShop = new SellerShop();
        sellerShop.setIconPath(iconPath);
        sellerShop.setMobile(mobile);
        sellerShop.setStatus("NONE");
        sellerShop.setName(name);
        sellerShop.setProjects(projects);
        sellerShop.setUserName(userName);
        sellerShop.setfUserId(userId);
        sellerShopRepository.save(sellerShop);
        return Result.ok();
    }
    @Transactional
    public Result saveSellerShopCheck(Set<Long> sellerShopIds,String status,String remark) {
        if (CollectionUtils.isNotEmpty(sellerShopIds)) {
            for (Long sellerShopId : sellerShopIds) {
                SellerShop sellerShop = sellerShopRepository.findById(sellerShopId).get();
                sellerShop.setStatus(status);
                //sellerShop.setRemark(remark);
                sellerShopRepository.saveAndFlush(sellerShop);
                if ("SUCCESS".equals(status)) {
                    Member member = memberRepository.findByUserId(sellerShop.getfUserId());
                    if (member != null) {
                        LocalUser localUser = localUserRepository.findById(member.getFUserId()).get();
                        if (localUser == null) {
                            localUser = new LocalUser();
                            localUser.setId(member.getFUserId());
                            localUser.setfUserId(member.getFUserId());
                            localUser.setUsername(member.getName());
                            localUser.setIconPath(sellerShop.getIconPath());
                            localUser.setPassword(DigestUtils.md5Hex(member.getMobile().substring(5)));
                            localUserRepository.save(localUser);
                            //商家角色ID
                            //if (!CollectionUtils.isEmpty(Collections.singletonList(this.valueConfigCache.getLong("role_id_shop_mini_program")))){
                            if (!CollectionUtils.isEmpty(Collections.singletonList(532383599442264064L))){
                                userRoleService.saveUserRole(new UserRoleModel(localUser.getfUserId(), new HashSet(Collections.singletonList(532383599442264064L))));
                            }
                            continue;
                        }
                        localUser.setIconPath(sellerShop.getIconPath());
                        localUser.setRemoved(Integer.valueOf(0));
                        localUserRepository.saveAndFlush(localUser);
                    }
                }
            }
        }
        return Result.ok();
    }
    @Transactional
    public Result deleteSellerShop(Long sellerShopId) {
        SellerShop sellerShop = sellerShopRepository.findById(sellerShopId).get();
        if (sellerShop != null) {
            this.localUserRepository.deleteByUserId(sellerShop.getfUserId());
            this.goodsRepository.deleteBySellerUserId(sellerShop.getfUserId());
            this.sellerShopRepository.deleteById(sellerShopId);
        }
        return Result.ok();
    }
    public Result<SellerShopDetailView> detailSellerShop(Long sellerShopId) {
        SellerShop sellerShop = sellerShopRepository.findById(sellerShopId).get();
        if (sellerShop == null) {
            return Result.failed(6001,"店铺不存在");
        }
        SellerShopDetailView view = new SellerShopDetailView();
        BeanUtils.copyProperties(sellerShop, view);
        List<AttachView> attachViews = this.attachService.findByBusinessId(view.getId());
        view.setAttachViews(attachViews);
        return Result.ok(view);
    }
    public Result<SellerShopDetailView> detailSellerShopByUserId(Long sellerUserId) {
        SellerShop sellerShop = sellerShopRepository.findByUserId(sellerUserId);
        if (sellerShop == null) {
            return Result.failed(6001,"店铺不存在");
        }
        SellerShopDetailView view = new SellerShopDetailView();
        BeanUtils.copyProperties(sellerShop, view);
        List<AttachView> attachViews = this.attachService.findByBusinessId(view.getId());
        view.setAttachViews(attachViews);
        return Result.ok(view);
    }

    public Result checkSellerShopByUserId() {
        Long userId = this.userSessionManager.getUserId();
        SellerShop sellerShop = this.sellerShopRepository.findByUserId(userId);
        if (sellerShop != null) {
            return Result.ok(true);
        } else {
            return Result.ok(false);
        }
    }

    public Result findBySellerShopMember(Long sellerUserId, String name) {
        SellerShop sellerShop = this.sellerShopRepository.findByUserId(sellerUserId);
        if (null == sellerShop) {
            return Result.failed(101,"商家不存在");
        }
        List<Order> orderList = this.orderRepository.findBySellerShopUserId(sellerUserId);
        if (CollectionUtils.isNotEmpty(orderList)) {
            Map<Long, List<Order>> collect = (Map<Long, List<Order>>)orderList.stream().collect(Collectors.groupingBy(Order::getUserId));
            Set<Long> userIds = collect.keySet();
            QMember qMember = QMember.member;
            BooleanBuilder builder = new BooleanBuilder();
            if (StringUtils.isNotEmpty(name)) {
                builder.and(qMember.name.like(name));
            }
            builder.and(qMember.fUserId.in(userIds));
            List<Member> fetch = queryFactory.select(
                    Projections.bean(
                            Member.class,
                            qMember.name,
                            qMember.fUserId,
                            qMember.id
                    )
            ).from(qMember).where(builder).fetch();
            return Result.ok(fetch);
        }
        return Result.ok();
    }

    public Result findBySellerShopStatistics(String dateType) {
        Long userId = this.userSessionManager.getUserId();
        SellerShop sellerShop = this.sellerShopRepository.findByUserId(userId);
        if (null == sellerShop) {
            return Result.failed(101,"店铺不存在或存在异常");
        }
        Map<String, Object> map = new HashMap<>();
        BigDecimal money = new BigDecimal(0);
        if ("TODAY".equals(dateType)) {
            money = this.orderRepository.findBySellerUserId1(sellerShop.getfUserId());
        } else if ("YESTERDAY".equals(dateType)) {
            money = this.orderRepository.findBySellerUserId2(sellerShop.getfUserId());
        } else if ("NEAR_WEEK".equals(dateType)) {
            money = this.orderRepository.findBySellerUserId3(sellerShop.getfUserId());
        }
        Integer orderCount = null;
        if ("TODAY".equals(dateType)) {
            orderCount = this.orderRepository.findBySellerOrderCount1(sellerShop.getfUserId());
        } else if ("YESTERDAY".equals(dateType)) {
            orderCount = this.orderRepository.findBySellerOrderCount2(sellerShop.getfUserId());
        } else if ("NEAR_WEEK".equals(dateType)) {
            orderCount = this.orderRepository.findBySellerOrderCount3(sellerShop.getfUserId());
        }
        List<Order> shopUserId = this.orderRepository.findBySellerShopUserId(sellerShop.getfUserId());
        Map<Long, List<Order>> collect = (Map<Long, List<Order>>)shopUserId.stream().collect(Collectors.groupingBy(Order::getUserId));
        Set<Long> shopUserIds = collect.keySet();
        Integer memberCount = Integer.valueOf(shopUserIds.size());
        map.put("money", money);
        map.put("orderCount", orderCount);
        map.put("memberCount", memberCount);
        return Result.ok(map);
    }


    public Result findByBranchDataStatistics(String dateType) {
        int i;
        Long userId = this.userSessionManager.getUserId();
        Member member = this.memberRepository.findByUserId(userId);
        SellerShop sellerShop = this.sellerShopRepository.findByUserId(userId);
        Map<String, Object> map = new HashMap<>();
        LocalDate localDate = LocalDate.now();
        List<String> dateList = new ArrayList<>();
        List<String> xAxisList = new ArrayList<>();
        List<BigDecimal> valueList = new ArrayList<>();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String lastTime = null;
        /*
        PRE_TODAY("今天以前"), TODAY("当天"), YESTERDAY("昨天"), THREE_DAY("近三天"),
        CURRENT_WEEK("本周"), NEAR_WEEK("近一周"),
        CURRENT_MONTH("本月"), LAST_MONTH("上个月"), NEAR_MONTH("近一个月"), THREE_MONTH("近三个月"),
        CURRENT_QUARTER("本季度"), LAST_QUARTER("上季度"), HALF_YEAR("近半年"),
        CURRENT_YEAR("今年"), LAST_YEAR("上一年");
        */
        switch (dateType) {
            case "TODAY":
                for (i = 6; i >= 0; i--) {
                    LocalDate date = localDate.minusDays(i);
                    String format = dateFormatter.format(date);
                    dateList.add(format);
                    if (i == 5) {
                        lastTime = dateFormatter.format(date);
                    }
                }
                break;
            case "YESTERDAY":
                for (i = 29; i >= 0; i--) {
                    LocalDate date = localDate.minusDays(i);
                    String format = dateFormatter.format(date);
                    dateList.add(format);
                    if (i == 28) {
                        lastTime = dateFormatter.format(date);
                    }
                }
                break;
            case "THREE_DAY":
                for (i = 5; i >= 0; i--) {
                    LocalDate date = localDate.minusMonths(i);
                    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
                    String format = dateTimeFormatter.format(date);
                    dateList.add(format);
                    if (i == 4) {
                        lastTime = dateFormatter.format(date);
                    }
                }
                break;
        }
        List<Map<String,Object>> countViews = null;
        if ("HALF_YEAR".equals(dateType)) {
            countViews = this.orderRepository.findOrderIncomeGroup1(lastTime, sellerShop.getfUserId());
         } else {
            countViews = this.orderRepository.findOrderIncomeGroup2(lastTime, sellerShop.getfUserId());
         }
        if (CollectionUtils.isEmpty(countViews)) {
            countViews = new ArrayList();
        }
        //Map<String, BigDecimal> viewMap = (Map<String, BigDecimal>)countViews.stream().collect(Collectors.toMap(Map<String,Object>::getTime, v -> v));
        Map<String, BigDecimal> resultMap = new HashMap<>();
        for (Map<String, Object> mp : countViews) {
            // 从map中获取时间属性和金额属性，并将金额属性转换为BigDecimal类型
            String time = (String) mp.get("time");
            BigDecimal money = new BigDecimal(mp.get("money").toString());
            // 将时间和金额添加到Map中
            resultMap.put(time, money);
        }
        for (String date : dateList) {
            BigDecimal countView = resultMap.get(date);
            if (countView == null || new BigDecimal(0).equals(countView)) {
                valueList.add(BigDecimal.ZERO);
            } else {
                valueList.add(countView);
            }
            String[] split = date.split("-");
            switch (dateType) {
                case "TODAY":
                case "YESTERDAY":
                    xAxisList.add(split[split.length - 1] + "日");
                case "THREE_DAY":
                    xAxisList.add(split[split.length - 1] + "月");
            }
        }
        map.put("dates", xAxisList);
        map.put("values", valueList);
        return Result.ok(map);
    }

    public Result findBySellerShopIncome() {
        Long userId = this.userSessionManager.getUserId();
        SellerShop sellerShop = this.sellerShopRepository.findByUserId(userId);
        if (null == sellerShop) {
            return Result.failed(101,"商家店铺不存在");
        }
        Map<String, Object> map = new HashMap<>();
        BigDecimal toDayMoney = this.orderRepository.findByToDayMoney(sellerShop.getfUserId());
        BigDecimal monthMoney = this.orderRepository.findByMonth(sellerShop.getfUserId());
        BigDecimal withdrawalsMoney = this.withdrawalsRecordRepository.findBySellerShopSumMoney(sellerShop.getfUserId());
        List<AssetDetail> sellerGoodsIncome = this.assetDetailRepository.findBySellerShopGoodsMoney(sellerShop.getfUserId());
        map.put("toDayMoney", toDayMoney);
        map.put("monthMoney", monthMoney);
        map.put("withdrawalsMoney", withdrawalsMoney);
        map.put("sellerGoodsIncome", sellerGoodsIncome);
        return Result.ok(map);
    }

}
